import copy
import datetime
import json
import threading

from django.http import HttpResponse
from django.shortcuts import render
import pytz

tz = pytz.timezone('Asia/Shanghai')
buffer_lock = {"test": {
    "isAlert": 0,
    "phoneState": 0,
    "videoType": 0,
    "lastTime": str(datetime.datetime.now())}
}
SECRET_KEY_HEART = "YUEksdi6775KNs94STNBXk32"
SECRET_KEY_API = "hj83YSKDLnmd7924KKsakksh"

lock = threading.Lock()  # 生成锁对象，全局唯一


# 状态查询
def stateMsg(request):
    data = {}
    data['data'] = _getBuffer()
    data['state'] = 200
    data['errMsg'] = "success!"
    return HttpResponse(json.dumps(data, ensure_ascii=False, indent=1))


# 公告接口
def notice(request):
    data = {}
    data['data'] = "【公告】欢迎使用四通钉自学。"
    data['state'] = 200
    data['errMsg'] = "success!"
    return HttpResponse(json.dumps(data, ensure_ascii=False, indent=1))


# 控制台前端
def web(request):
    doHtml = """
    <html><head><meta http-equiv="refresh" content="0;url=static/farm/index.html"></head></html>
    """
    return HttpResponse(doHtml)


# 控制台后端
def api(request):
    """
    通过该功能写缓存
    写入依据优先级 phoneId>ddId>wechatId>userPhoneNumber
    :param request:
    :return:
    """
    arguments = _getArguments(request)
    if arguments.get("secretKey", "") != SECRET_KEY_API:
        returnDict = {
            "state": 550,
            "errMsg": "secretKey错误!"
        }
        return HttpResponse(json.dumps(returnDict, ensure_ascii=False, indent=1))
    phoneId = arguments["phoneId"]
    isAlert = int(arguments.get("isAlert", 0))
    videoType = int(arguments.get("videoType", 0))
    _makeItem(phoneId, None, isAlert, videoType)
    returnDict = {
        "input": arguments,
        "state": 200,
        "errMsg": "success!"
    }
    print("内容返回")
    print(returnDict)
    return HttpResponse(json.dumps(returnDict, ensure_ascii=False, indent=1))


# 心跳
def heart(request):
    """
    心跳接口，负责状态传达和报警指令下发。播放阶段10秒/次心跳，休息状态3秒/次心跳，报警状态1秒1次心跳。
    错误码 550 secretKey错误
    错误码 551 未注册该phoneId
    :param
    state:状态参数，不可为空。
    0代表闲置状态，1代表播放状态，2代表报警状态。
    1定义：触发长流量规则后40分钟内都视为播放状态（麻烦调研一下是否有更准确的流量规则定义播放状态，那就更好了）
    2定义：振铃未被关停视为报警状态
    0定义：休息状态
    phoneId:手机ID，不可为空。
    :return:
    data.isAlert:报警接口，若为1则触发报警，若为0则不触发报警。
    """
    arguments = _getArguments(request)
    if arguments.get("secretKey", "") != SECRET_KEY_HEART:
        returnDict = {
            "state": 550,
            "errMsg": "secretKey错误!"
        }
        return HttpResponse(json.dumps(returnDict, ensure_ascii=False, indent=1))
    # 查看是否注册了该手机
    data = _getBuffer().get(arguments.get("phoneId"), None)
    if data is None:
        _makeItem(arguments.get("phoneId"), arguments.get("state"), 0, 0)
        returnDict = {
            "state": 202,
            "errMsg": "已注册该phoneId!"
        }
    else:
        returnDict = {
            "input": arguments,
            "data": copy.deepcopy(data),
            "isAlert": copy.deepcopy(data)['isAlert'],
            "videoType": copy.deepcopy(data)['videoType'],
            "state": 200,
            "errMsg": "success!"
        }
        # 对data进行修正,只要响应过就重置为0
        _makeItem(arguments.get("phoneId"), arguments.get("state"), 0, 0)
    # print("heart phoneId={} time={}".format(arguments.get("phoneId"), datetime.datetime.now()))
    # print("内容返回")
    # print(returnDict)
    return HttpResponse(json.dumps(returnDict, ensure_ascii=False, indent=1))


def _makeItem(phoneId, phoneState, isAlert, videoType):
    if phoneState is None:
        phoneState = _getBuffer()[phoneId]['phoneState']
    if isAlert is None:
        isAlert = _getBuffer()[phoneId]['isAlert']
    if videoType is None:
        videoType = _getBuffer()[phoneId]['videoType']
    _getBuffer()[phoneId] = {
        "isAlert": isAlert,
        "videoType": videoType,
        "phoneState": phoneState,
        "lastTime": str(datetime.datetime.now(tz=tz))
    }
    return True


def _setBuffer(bufferNow):
    lock.acquire()  # 获取锁。未获取到的线程会阻塞程序，直到获取到锁才会往下执行
    try:
        buffer_lock = bufferNow
        return bufferNow
    finally:
        lock.release()  # 释放锁，归回锁，其他线程可以拿去用了


def _getBuffer():
    lock.acquire()  # 获取锁。未获取到的线程会阻塞程序，直到获取到锁才会往下执行
    try:
        return buffer_lock
    finally:
        lock.release()  # 释放锁，归回锁，其他线程可以拿去用了


def _getArguments(request):
    if request.method == 'GET':
        # print("收到GET请求")
        arguments = dict(request.GET)
        for arg in arguments:
            if type(arguments[arg]) == type([]):
                arguments[arg] = arguments[arg][0]
    else:
        # print("收到POST请求")
        # print("post-body")
        print(request.body.decode())
        arguments = json.loads(request.body.decode())
    return arguments
